# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File       : task_instance_view.py
# Time       ：2023/3/12 13:21
# Author     ：Y-aong
# version    ：python 3.7
# Description：
    任务实例视图
    task instance views
"""
from flask import request
from flask_restx import fields

from apis.orderlines import orderlines_ns
from apis.orderlines.models.task import TaskInstance
from apis.orderlines.schema.task_schema import TaskInstanceSchema, TaskInstanceLogSchema
from apis.orderlines.views import task_config_item_model
from public.api_utils.api_decorator import handle_api_error
from public.base_export_excel_view import BaseExportExcelView
from public.base_model import db
from public.base_response import MarshalModel, generate_response
from public.base_view import BaseView, BaseDetailsView, AbstractView

task_instance = {
    'id': fields.String(description='任务实例ID'),
    'task_instance_id': fields.String(description='任务运行ID'),
    'task_index_id': fields.String(description='任务运行顺序ID'),
    'task_name': fields.String(description='任务名称'),
    'process_name': fields.String(description='进程名称'),
    'task_type': fields.String(description='任务类型'),
    'task_module': fields.String(description='任务模块'),
    'task_config': fields.List(fields.Nested(task_config_item_model), description='任务配置'),
    'method_name': fields.String(description='任务执行方法名称'),
    'method_kwargs': fields.Raw(description='任务执行参数'),
    'task_status': fields.String(description='任务运行实例状态'),
    'start_time': fields.String(description='任务实例开始时间'),
    'end_time': fields.String(description='任务实例结束时间'),
    'runner': fields.String(description='任务执行者'),
    'runner_id': fields.String(description='任务执行者ID'),
    'task_result': fields.String(description='任务返回结果'),
    'task_error_info': fields.Raw(description='任务运行错误信息'),
    'result_config': fields.Raw(description='结果配置'),
    'task_desc': fields.String(description='任务描述'),
    'mode': fields.String(description='任务运行模式'),
    'logs': fields.String(description='任务实例日志'),
    'message_id': fields.String(description='任务队列ID'),
    'process_id': fields.String(description='流程ID'),
    'process_instance_id': fields.String(description='流程实例ID'),
    'task_id': fields.String(description='任务ID'),
}

task_instance_detail = {
    'task_id': fields.String(),
    'process_instance_id': fields.String(),
}
task_instance_marshal = MarshalModel('task_instance', orderlines_ns)


class TaskInstanceDetailView(AbstractView):
    url = '/task_instance_detail'

    def __init__(self, *args, **kwargs):
        super(TaskInstanceDetailView, self).__init__(*args, **kwargs)
        self.form_data = request.args
        self.task_id = self.form_data.get('task_id')
        self.process_instance_id = self.form_data.get('process_instance_id')

    @handle_api_error()
    @orderlines_ns.doc(description='获取任务实例根据流程实例id和任务id')
    @orderlines_ns.expect(task_instance_marshal.detail_request(task_instance_detail))
    @orderlines_ns.marshal_with(task_instance_marshal.detail_response(task_instance))
    def get(self):
        """获取任务实例根据流程实例id和任务id"""
        obj = db.session.query(TaskInstance).filter(
            TaskInstance.process_instance_id == self.process_instance_id,
            TaskInstance.task_id == self.task_id
        ).first()
        if obj is None:
            raise ValueError(f'process_instance_id::{self.process_instance_id},task_id::{self.task_id} can not find')
        info = TaskInstanceLogSchema().dump(obj)
        return generate_response(info)


class TaskInstanceDetailIDView(BaseDetailsView):
    url = '/task_instance/detail'

    def __init__(self, *args, **kwargs):
        super(TaskInstanceDetailIDView, self).__init__(*args, **kwargs)
        self.table_orm = TaskInstance
        self.table_schema = TaskInstanceSchema
        self.task_id = self.form_data.get('task_id')
        self.process_instance_id = self.form_data.get('process_instance_id')

    @handle_api_error()
    @orderlines_ns.doc(description="获取任务实例详情")
    @orderlines_ns.expect(task_instance_marshal.detail_request())
    @orderlines_ns.marshal_with(task_instance_marshal.detail_response(task_instance))
    def get(self):
        """获取任务实例详情"""
        return super(TaskInstanceDetailIDView, self).get()


class TaskInstanceView(BaseView):
    url = '/task_instance'

    def __init__(self, *args, **kwargs):
        super(TaskInstanceView, self).__init__(*args, **kwargs)
        self.table_orm = TaskInstance
        self.table_schema = TaskInstanceSchema

    def handle_filter(self):
        self.filter.append(self.table_orm.active == 1)
        for key, val in self.form_data.items():
            if hasattr(self.table_orm, key) and val and key != 'process_instance_id':
                self.filter.append(getattr(self.table_orm, key) == val)
            elif key == 'process_instance_id' and val:
                self.filter.append(self.table_orm.process_instance_id.in_(val.split(',')))

    @handle_api_error()
    @orderlines_ns.doc(description='获取流程列表')
    @orderlines_ns.expect(task_instance_marshal.list_request(task_instance))
    @orderlines_ns.marshal_with(task_instance_marshal.list_response(task_instance))
    def get(self):
        """获取流程列表"""
        return super(TaskInstanceView, self).get()

    @handle_api_error()
    @orderlines_ns.doc(description='创建任务实例')
    @orderlines_ns.expect(task_instance_marshal.create_request(task_instance))
    @orderlines_ns.marshal_with(task_instance_marshal.create_response())
    def post(self):
        """创建任务实例"""
        return super(TaskInstanceView, self).post()

    @handle_api_error()
    @orderlines_ns.doc(description='修改任务实例')
    @orderlines_ns.expect(task_instance_marshal.update_request(task_instance))
    @orderlines_ns.marshal_with(task_instance_marshal.update_response())
    def put(self):
        """修改任务实例"""
        return super(TaskInstanceView, self).put()

    @handle_api_error()
    @orderlines_ns.doc(description='删除任务实例')
    @orderlines_ns.expect(task_instance_marshal.delete_request())
    @orderlines_ns.marshal_with(task_instance_marshal.delete_response())
    def delete(self):
        """删除任务实例"""
        return super(TaskInstanceView, self).delete()


class TaskInstanceReportView(BaseExportExcelView):
    url = '/task_instance/export'

    def __init__(self, *args, **kwargs):
        super(TaskInstanceReportView, self).__init__(*args, **kwargs)
        from datetime import datetime
        self.file_name = f'task_{datetime.now().strftime("%Y-%m-%d")}'
        self.columns = {
            'id': '序号',
            'process_id': '流程id',
            'task_id': '任务id',
            'task_name': '任务名称',
            'method_name': '方法名称',
            'start_time': '开始时间',
            'end_time': '结束时间',
            'creator': '创建者',
            'task_type': '任务类型',
            'task_module': '任务模块',
            'module_version': '模块版本',
            'task_desc': '任务描述',
            'task_result': '任务结果',
            'task_error_info': '异常信息'
        }

    @handle_api_error()
    @orderlines_ns.doc(description='导出任务实例')
    @orderlines_ns.expect(task_instance_marshal.list_request(task_instance))
    def post(self):
        """导出任务实例"""
        return super(TaskInstanceReportView, self).post()
